package com.ymx.darling.bean.sql;

import com.ymx.darling.bean.entity.BeanInfo;
import com.ymx.darling.bean.entity.BeanInfoManager;
import com.ymx.darling.dialect.keygenerator.KeyGenerator;
import com.ymx.darling.build.Configuration;
import com.ymx.darling.build.mapper.dynamic.result.ResultMapNode;
import com.ymx.darling.executor.Executor;
import com.ymx.darling.executor.cache.CacheKey;
import com.ymx.darling.executor.statement.StatementType;
import com.ymx.darling.log.Log;
import com.ymx.darling.session.setting.Callable;
import com.ymx.darling.session.setting.relation.RelationEntity;

import java.util.*;

/**
 * 对一条sql进行封装
 *
 * @author 爱java的小于
 */
public class Statement {
    /**全局配置实例*/
    private Configuration configuration;
    /**执行器*/
    private Executor executor;
    /**sql语句的缓存的key*/
    private CacheKey cacheKey;
    /**sql语句的id*/
    private String statementId;
    /**封装sql及其参数绑定的实例**/
    private BoundSql boundSql;
    /**缓存的命名空间 也就是mapper的Class*/
    private Class<?> namespace;
    /**sql的类型 select delete update insert*/
    private SqlCommandType sqlCommandType;
    /**保存自定义结果映射*/
    private ResultMapNode resultMapNode;
    /**设置级联操作列表*/
    private RelationEntity relationEntity;
    /**级联查询时的参数*/
    private Map<String, Object> nestedQueryParam;
    /**结果集的映射类型**/
    private Class<?> module;
    /**游标查询时一次性从数据库读取的数据 默认值-1表示不为游标查询*/
    private int faceSize = -1;
    /**日志实例*/
    private Log logger;
    /**存储过程参数等信息*/
    private Callable callable;
    /**本次查询缓存是否有效 默认为有效*/
    private boolean useCache = true;
    /**批量插入时一次插入的记录数 默认值null表示不进行批量插入*/
    private int insertBatchSize;
    /**主键生成策略*/
    private KeyGenerator keyGenerator;
    /**statement的类型 默认为{@code StatementType.PREPARED}*/
    private StatementType statementType = StatementType.PREPARED;

    public void setInsertBatchSize(int insertBatchSize) {
        this.insertBatchSize = insertBatchSize;
    }

    public int getInsertBatchSize() {
        return insertBatchSize;
    }

    public void setKeyGenerator(KeyGenerator keyGenerator) {
        this.keyGenerator = keyGenerator;
    }

    public KeyGenerator getKeyGenerator() {
        return keyGenerator;
    }

    public void setSqlCommandType(SqlCommandType sqlCommandType) {
        this.sqlCommandType = sqlCommandType;
    }

    public SqlCommandType getSqlCommandType() {
        return sqlCommandType;
    }

    public void setStatementId(String statementId) {
        this.statementId = statementId;
    }

    public String getStatementId() {
        return statementId;
    }

    public void setStatementType(StatementType statementType) {
        this.statementType = statementType;
    }

    public StatementType getStatementType() {
        return statementType;
    }

    public void setCallable(Callable callable) {
        this.callable = callable;
    }

    public Callable getCallable() {
        return callable;
    }

    public void setResultMapNode(ResultMapNode resultMapNode) {
        this.resultMapNode = resultMapNode;
    }

    public ResultMapNode getResultMapNode() {
        return resultMapNode;
    }

    public void setRelationEntity(RelationEntity relationEntity) {
        this.relationEntity = relationEntity;
    }

    public RelationEntity getRelationEntity() {
        return relationEntity;
    }

    public void setNestedQueryParam(Map<String, Object> nestedQueryParam) {
        this.nestedQueryParam = nestedQueryParam;
    }

    public Map<String, Object> getNestedQueryParam() {
        return nestedQueryParam;
    }

    public void setConfiguration(Configuration configuration) {
        this.configuration = configuration;
    }

    public Configuration getConfiguration() {
        return configuration;
    }

    public void setExecutor(Executor executor) {
        this.executor = executor;
    }

    public Executor getExecutor() {
        return executor;
    }

    public List<RelationEntity> getQueryPropertyList() {
        return Objects.isNull(this.relationEntity) ? null : this.relationEntity.getQueryPropertyList();
    }

    public boolean hasRelationProperty() {
        return Objects.nonNull(this.relationEntity) && relationEntity.hasAssociationQueryField();
    }

    public void setBoundSql(BoundSql boundSql) {
        this.boundSql = boundSql;
    }

    public BoundSql getBoundSql() {
        return boundSql;
    }

    /**
     * 判断是否是自定义映射
     * @return boolean
     */
    public boolean isCustomMapping() {
        return this.resultMapNode != null;
    }

    /**
     * 返回当前sql的缓存的key
     * @return String
     */
    public CacheKey getSqlKey() {
        if (Objects.isNull(this.cacheKey)) {
            this.cacheKey = new CacheKey(this);
        }
        return this.cacheKey;
    }

    public void setUseCache(boolean useCache) {
        this.useCache = useCache;
    }

    public boolean isUseCache() {
        return useCache;
    }

    public void setModule(Class<?> module) {
        this.module = module;
    }

    public Class<?> getModule(){
        return this.module;
    }

    public BeanInfo getBeanInfo() {
        return BeanInfoManager.getBeanInfo(this.module);
    }

    public void setNamespace(Class<?> namespace) {
        this.namespace = namespace;
    }

    public Class<?> getNamespace() {
        return namespace;
    }

    public void setFaceSize(int faceSize) {
        this.faceSize = faceSize;
    }

    public int getFaceSize() {
        return faceSize;
    }

    public void setLogger(Log logger) {
        this.logger = logger;
    }

    public Log getLogger() {
        return logger;
    }

    public Object getParam() {
        return null;
    }

    public String getSqlStatement() {
        return null;
    }
}
